﻿using System.Collections;
using System.Collections.Generic;
using System.Data;
using MyCement.Database;
using MyCement.Database.Collection;
using MyCement.Database.Transaction;
using MyCement.Utils;

namespace OA.Business
{
    /// <summary>
    /// BusinessFactory interface
    /// </summary>
    public interface IBusinessFactory
    {
    }
    /// <summary>
    /// BusinessFactory Base
    /// </summary>
    public abstract class BusinessFactory : IBusinessFactory
    {

    }
    /// <summary>
    /// BusinessBase interface
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="TKey"></typeparam>
    public interface IBusinessBase<T, in TKey> where T : class
    {
        T GetById(string field, TKey id);
        T QueryForObject(string query);
        T QueryForObject(string field, object entity);

        List<T> QueryForList(string query);
        List<T> QueryForList(string query, PageStructure page);
        List<TClass> QueryForList<TClass>(string query, PageStructure page) where TClass : class;

        List<T> QueryForList(string field, object entity);
        List<T> QueryForList(string field, object entity, PageStructure page);
        List<TClass> QueryForList<TClass>(string field, object entity, PageStructure page) where TClass : class;

        List<TValue> QueryForUnique<TValue>(string query);
        List<TValue> QueryForUnique<TValue>(string query, PageStructure page);
        List<TValue> QueryForUnique<TValue>(string field, object entity);
        List<TValue> QueryForUnique<TValue>(string field, object entity, PageStructure page);

        DataSet QueryForDataSet(string field, object entity);
        DataSet QueryForDataSet(string query);

        MapResult QueryForMap(string field, object entity);
        MapResult QueryForMap(string query);

        object QueryForScalar(string field, object entity);
        object QueryForScalar(string query);

        /// <summary>
        /// 不执行规则判断新增
        /// </summary>
        object Insert(string field, T entity);
        /// <summary>
        /// 不执行规则判断新增
        /// </summary>
        object Insert(string field, Hashtable entity);

        /// <summary>
        /// 不执行规则判断新增
        /// </summary>
        object Insert(string query);

        /// <summary>
        /// 不执行规则判断删除
        /// </summary>
        int Delete(string field, T entity);
        /// <summary>
        /// 不执行规则判断删除
        /// </summary>
        int Delete(string field, Hashtable entity);

        /// <summary>
        /// 不执行规则判断删除
        /// </summary>
        int Delete(string query);

        /// <summary>
        /// 不执行规则判断更新
        /// </summary>
        int Update(string field, T entity);
        /// <summary>
        /// 不执行规则判断更新
        /// </summary>
        int Update(string field, Hashtable entity);

        /// <summary>
        /// 不执行规则判断更新
        /// </summary>
        int Update(string query);

        /// <summary>
        /// 开始事务处理
        /// </summary>
        void BeginTransaction();

        /// <summary>
        /// 开始事务处理
        /// </summary>
        void BeginTransaction(IsolationLevel level);

        /// <summary>
        /// 提交事务处理
        /// </summary>
        void CommitTransaction();

        /// <summary>
        /// 回滚事务处理
        /// </summary>
        void RollbackTransaction();

        /// <summary>
        /// 有无事务处理
        /// </summary>
        bool HasTransaction { get; }
    }
    /// <summary>
    /// BusinessBase
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="TKey"></typeparam>
    public abstract class BusinessBase<T, TKey> : IBusinessBase<T, TKey> where T : class
    {
        protected ITransaction transaction = null;
        protected IDataSession MainConn;
        protected IDataSession SliveConn;

        protected BusinessBase()
        {
            MainConn = SessionManager.Instance.CreateSession(SessionTypes.Master);
            SliveConn = SessionManager.Instance.CreateSession(SessionTypes.Slive);
        }

        #region QueryForObject

        public virtual T GetById(string field, TKey id)
        {
            return QueryForObject(field, id);
        }

        public virtual T QueryForObject(string query)
        {
            if (SliveConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            return SliveConn.QueryForObject<T>(query);
        }

        public virtual T QueryForObject(string field, object entity)
        {
            if (SliveConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            return SliveConn.QueryForObject<T>(field, entity);
        }
        #endregion

        #region QueryForList

        public virtual List<T> QueryForList(string query)
        {
            return QueryForList(query, null);
        }

        public virtual List<T> QueryForList(string query, PageStructure page)
        {
            return QueryForList<T>(query, page);
        }

        public virtual List<TClass> QueryForList<TClass>(string query, PageStructure page) where TClass : class
        {
            if (SliveConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            return SliveConn.QueryForList<TClass>(query, page);
        }

        public virtual List<T> QueryForList(string field, object entity)
        {
            return QueryForList(field, entity, null);
        }

        public virtual List<T> QueryForList(string field, object entity, PageStructure page)
        {
            return QueryForList<T>(field, entity, page);
        }

        public virtual List<TClass> QueryForList<TClass>(string field, object entity, PageStructure page) where TClass : class
        {
            if (SliveConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            return SliveConn.QueryForList<TClass>(field, entity, page);
        }
        #endregion

        #region QueryForUnique

        public List<TValue> QueryForUnique<TValue>(string query)
        {
            return QueryForUnique<TValue>(query, null);
        }

        public List<TValue> QueryForUnique<TValue>(string query, PageStructure page)
        {
            return SliveConn.QueryForUnique<TValue>(query, page);
        }

        public List<TValue> QueryForUnique<TValue>(string field, object entity)
        {
            return QueryForUnique<TValue>(field, entity, null);
        }

        public List<TValue> QueryForUnique<TValue>(string field, object entity, PageStructure page)
        {
            if (SliveConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            return SliveConn.QueryForUnique<TValue>(field, entity, page);
        }
        #endregion

        #region QueryForDataSet

        public virtual DataSet QueryForDataSet(string field, object entity)
        {
            if (SliveConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }

            return SliveConn.QueryForDataSet(field, entity);
        }

        public virtual DataSet QueryForDataSet(string query)
        {
            if (SliveConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }

            return SliveConn.QueryForDataSet(query);
        }
        #endregion

        #region QueryForMap

        public MapResult QueryForMap(string field, object entity)
        {
            if (SliveConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            return SliveConn.QueryFormMap(field, entity);
        }

        public MapResult QueryForMap(string query)
        {
            if (SliveConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            return SliveConn.QueryFormMap(query);
        }

        #endregion

        #region QueryForScalar

        public virtual object QueryForScalar(string field, object entity)
        {
            if (SliveConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            return SliveConn.QueryForScalar(field, entity);
        }

        public virtual object QueryForScalar(string query)
        {
            if (SliveConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            return SliveConn.QueryForScalar(query);
        }

        #endregion

        #region CRUD Methods
        /// <summary>
        /// 不执行规则判断新增
        /// </summary>
        public virtual object Insert(string field, T entity)
        {
            if (MainConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            return MainConn.Insert(field, entity);
        }

        public object Insert(string field, Hashtable entity)
        {
            if (MainConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            return MainConn.Insert(field, entity);
        }

        /// <summary>
        /// 不执行规则判断新增
        /// </summary>
        public virtual object Insert(string query)
        {
            if (MainConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            return MainConn.Insert(query);
        }

        /// <summary>
        /// 不执行规则判断删除
        /// </summary>
        public virtual int Delete(string field, T entity)
        {
            if (MainConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            return MainConn.Delete(field, entity);
        }

        public int Delete(string field, Hashtable entity)
        {
            if (MainConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            return MainConn.Delete(field, entity);
        }

        /// <summary>
        /// 不执行规则判断删除
        /// </summary>
        public virtual int Delete(string query)
        {
            if (MainConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            return MainConn.Delete(query);
        }

        /// <summary>
        /// 不执行规则判断更新
        /// </summary>

        public virtual int Update(string field, T entity)
        {
            if (MainConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            return MainConn.Update(field, entity);
        }

        public int Update(string field, Hashtable entity)
        {
            if (MainConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            return MainConn.Update(field, entity);
        }

        /// <summary>
        /// 不执行规则判断更新
        /// </summary>
        public virtual int Update(string query)
        {
            if (MainConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            return MainConn.Update(query);
        }

        #endregion

        #region Transaction Methiods

        /// <summary>
        /// 开始事务处理
        /// </summary>
        public virtual void BeginTransaction()
        {
            if (MainConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            bool result = MainConn.HasOpenTransaction;
            if (!result)
            {
                transaction = MainConn.BeginTransaction();
            }
        }

        /// <summary>
        /// 开始事务处理
        /// </summary>
        public virtual void BeginTransaction(IsolationLevel level)
        {
            if (MainConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            bool result = MainConn.HasOpenTransaction;
            if (!result)
            {
                transaction = MainConn.BeginTransaction(level);
            }
        }

        /// <summary>
        /// 提交事务处理
        /// </summary>
        public virtual void CommitTransaction()
        {
            if (MainConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            bool result = MainConn.HasOpenTransaction;
            if (result)
            {
                MainConn.CommitTransaction();
            }
        }

        /// <summary>
        /// 回滚事务处理
        /// </summary>
        public virtual void RollbackTransaction()
        {
            if (MainConn == null)
            {
                throw new BusinessException("Invalid_IDataSession_Type");
            }
            bool result = MainConn.HasOpenTransaction;
            if (result)
            {
                MainConn.RollbackTransaction();
            }
        }

        /// <summary>
        /// 有无事务处理
        /// </summary>
        public virtual bool HasTransaction
        {
            get
            {
                if (MainConn == null)
                {
                    return false;
                }
                return (transaction != null && transaction.IsActive);
            }
        }
        #endregion

    }
}
